package org.hs.phd.odi.tracking.tracker.particlefilter.core;

import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class ParticleFilter<T> {
	
	
	private final TransitionModel<T> transitionModel;
	private final ObservationModel<T> observationModel;

	private Particle<T>[] particles;
	private final ResamplingStrategy<T> resamplingStrategy;
	private boolean debugEnabled;


//	public ParticleFilter( int numberOfParticles, int w, int h, ObservationModel<T> observationModel){
//		this( numberOfParticles ,new AutoRegressiveDynamicsTransitionModel(w, h), observationModel, new ImportanceResamplingStrategy<T>());
//	}
	
	
	@SuppressWarnings("unchecked")
	public ParticleFilter(int numberOfParticles, TransitionModel<T> transitionModel, ObservationModel<T> observationModel, ResamplingStrategy<T> resamplingStrategy){
		this.transitionModel = transitionModel;
		this.observationModel = observationModel;
		this.resamplingStrategy = resamplingStrategy;
		particles = new Particle[numberOfParticles];
	}
	
	
	public void initParticlesFromSingleParticle(Particle<T> p){
		  
	      for( int i = 0; i < particles.length; i++ )
			{
		      particles[i] = p.clone();
			}

	}

	
	public void computeNextGeneration( IplImage nextFrame ){
		for (int i = 0; i < particles.length; i++) {
			particles[i] = transitionModel.transition(particles[i]);
			particles[i].setWeight( observationModel.computeLikelihood(nextFrame, particles[i]));
		}
		particles = resamplingStrategy.resample(particles);
		
		if(debugEnabled){
			System.out.println("\nNEXT GEN PARTICLES:");
			
			for (int i = 0; i < particles.length; i++) {
				System.out.println( i + "- " + particles[i].getCurrentState() + " : " + particles[i].getWeight());
				
			}
		}
	}
	
	public Particle<T> getMostLikelyParticle(){
		return particles[0];
	}


	public boolean isDebugEnabled() {
		return debugEnabled;
	}


	public void setDebugEnabled(boolean debugEnabled) {
		this.debugEnabled = debugEnabled;
	}
	
	
	
}
